package com.example.orderservice.service.Impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.example.orderservice.constants.MQConstants;
import com.example.orderservice.domain.dto.OrderPayDTO;
import com.example.orderservice.domain.entity.Good;
import com.example.orderservice.domain.entity.Order;
import com.example.orderservice.domain.entity.coupon;
import com.example.orderservice.domain.entity.item;
import com.example.orderservice.domain.vo.pointVo;
import com.example.orderservice.mapper.OrderMapper;
import com.example.orderservice.service.IOrderService;
import com.example.orderservice.utils.CurrentHoler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;


/**
 * 订单服务实现类
 * 处理订单创建、支付、查询等核心业务逻辑
 *
 * @author czwa
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    private final OrderMapper orderMapper;
    private final RabbitTemplate rabbitTemplate;

    /**
     * 创建订单（带事务管理）
     * 1. 校验库存
     * 2. 扣减库存
     * 3. 保存订单信息
     * 4. 发送延迟消息（5分钟未支付自动取消）
     *
     * @param order 订单实体
     * @return 订单编号
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String addOrder(Order order) {
        // 校验库存
        List<item> list = orderMapper.checkStock(order.getItems());
        for (item i : list) {
            if (i.getQuantity() < 1) {
                throw new RuntimeException(i.getGoodName() + "库存不足，试试别的吧＞﹏＜");
            }
        }

        // 校验购买数量
        for (item i : order.getItems()) {
            if (i.getQuantity() < 0) {
                throw new RuntimeException("商品数量出错了");
            }
            for (item good : list) {
                if (good.getGoodId() == i.getGoodId() && good.getQuantity() < i.getQuantity()) {
                    throw new RuntimeException(good.getGoodName() + "库存不足，试试别的吧＞﹏＜");
                }
            }
        }

        // 设置用户ID并保存订单
        order.setUserId(CurrentHoler.getCurrentId());
        orderMapper.saveOrder(order);
        int orderId = order.getId();

        // 扣减库存并关联订单商品
        orderMapper.batchDeductStock(order.getItems());
        orderMapper.addOrderToGoods(order.getItems(), orderId);

        // 发送延迟消息（5分钟后检查订单状态）
        rabbitTemplate.convertAndSend(
                MQConstants.DELAY_EXCHANGE_NAME,
                MQConstants.DELAY_ORDER_KEY,
                orderId,
                message -> {
                    message.getMessageProperties().setDelay(1000 * 60 * 5);
                    return message;
                }
        );

        return "下单成功,订单编号:" + orderId;
    }

    /**
     * 获取用户所有订单
     *
     * @return 订单列表
     */
    @Override
    public List<Order> getAllOrder() {
        return orderMapper.getAllOrder(CurrentHoler.getCurrentId());
    }

    /**
     * 获取用户未支付订单
     *
     * @return 未支付订单列表
     */
    @Override
    public List<Order> getNoPaidOrder() {
        return orderMapper.getNoPaidOrder(CurrentHoler.getCurrentId());
    }

    /**
     * 获取用户已处理订单
     *
     * @return 已处理订单列表
     */
    @Override
    public List<Order> getProcessedOrder() {
        return orderMapper.getProcessedOrder(CurrentHoler.getCurrentId());
    }

    /**
     * 获取用户已取消订单
     *
     * @return 已取消订单列表
     */
    @Override
    public List<Order> getCanceledOrder() {
        return orderMapper.getCanceledOrder(CurrentHoler.getCurrentId());
    }

    /**
     * 订单支付处理（带事务管理）
     * 1. 处理优惠券
     * 2. 扣减用户余额
     * 3. 更新订单状态
     * 4. 发送积分增加消息
     *
     * @param order 支付DTO
     */
    @Override
    @Transactional
    public void payOrder(OrderPayDTO order) {
        // 处理优惠券
        if (order.getCouponId() != null) {
            orderMapper.updateCouponStatus(order.getUid().intValue());
            coupon coupon = orderMapper.getCouponById(Math.toIntExact(order.getCouponId()));

            if (coupon.getStatus() != 1) {
                throw new RuntimeException("优惠券状态异常");
            }

            if (coupon.getMinAmount() > order.getExpend()) {
                throw new RuntimeException("优惠券使用条件未达到");
            }

            // 计算使用优惠券后的金额
            order.setExpend(order.getExpend() - coupon.getValue());
        }

        // 扣减用户余额
        int result = orderMapper.updateUserBalance(order.getExpend(), order.getUserId());
        if (result != 1) {
            throw new RuntimeException("支付行为出现异常了,请检查余额");
        }

        // 更新订单状态为已支付
        orderMapper.payOrder(Math.toIntExact(order.getId()));

        // 发送积分增加消息
        rabbitTemplate.convertAndSend("point.direct", "point.success",
                new pointVo(order.getUserId(), order.getExpend()));
    }

    /**
     * 取消支付（恢复库存）
     *
     * @param orderId 订单ID
     */
    @Override
    public void cancelPay(int orderId) {
        // 获取订单商品信息
        List<Good> goods = orderMapper.getGoodsByOrderId(orderId);

        // 恢复库存
        orderMapper.updateGoodStock(goods);

        // 更新订单状态为已取消
        UpdateWrapper<Order> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("status", 2).eq("id", orderId);
        orderMapper.update(updateWrapper);
    }

    /**
     * 增加用户积分（带事务管理）
     * 1. 增加积分和经验值
     * 2. 检查是否满足升级条件
     * 3. 升级后发放优惠券
     *
     * @param pointVo 积分VO
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addPoint(pointVo pointVo) {
        // 增加积分和经验值
        orderMapper.addPoint(pointVo);

        // 检查是否满足升级条件
        int success = orderMapper.checkExp(pointVo.getUserId());

        // 升级成功则发放优惠券
        if (success == 1) {
            orderMapper.addLevelCoupon(pointVo.getUserId(), 53);
        }
    }
}
